<?php

/* 微信公众平台 */

class WeixinApp extends MallbaseApp {

    var $ToUserName = ''; #开发者微信号
    var $FromUserName = ''; #发送方帐号（一个OpenID）
    var $MsgType = ''; #消息类型，event
    var $MsgEvent = ''; #事件类型，
    var $EventKey = ''; #事件KEY值
    var $CreateTime = '';
    var $my_wxkeyword_mod;
    var $_member_mod;
    var $_nickname; #微信号获取到的别名
    var $_unionid;
    var $_user_id = 0; #此微信号在本网站的用户ID
    var $_user_name = ''; #此微信号在本网站的用户名
    var $_third_login_id; #third_login 表中的主键ID 
    var $_scene_id = 0; #扫码推荐注册的ID ， 当注册新用户的时候，此ID为他的推荐人ID
    var $_third_login_mod;
    var $_change_refer; #当微信取消关注之后，重新通过二维码扫描可以使他的推荐人发生变化

    function __construct() {
        $this->WeixinApp();
    }

    function WeixinApp() {
        parent::__construct();
        $this->my_wxkeyword_mod = & m('wxkeyword');
        $this->_third_login_mod = & m('third_login');
        $this->_member_mod = & m('member');
        $this->_change_refer = 1;
    }
    function traceHttp() {
        $this->logger("<hr>");
        $this->logger(date('Y-m-d H:i:s')
                . " REMOTE_ADDR : "
                . $_SERVER["REMOTE_ADDR"]
                . ( strpos($_SERVER["REMOTE_ADDR"], "101.226.") !== False ? " FROM WeiXin " : " Unknown IP " )
                . strpos($_SERVER["REMOTE_ADDR"], "101.226")
        );
        $this->logger(date('Y-m-d H:i:s') . " QUERY_STRING : " . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING']);
    }
    function logger($content) {
        file_put_contents("log.html", $content . "<br>", FILE_APPEND);
    }

    function index() {
        $this->traceHttp();
        $token = Conf::get('payment_wx_token');
        if (empty($token)) {
            exit;
        }

        $signature = $_GET['signature'];
        $timestamp = $_GET['timestamp'];
        $nonce = $_GET['nonce'];
        $echostr = $_GET['echostr'];
        $arr = array($token, $timestamp, $nonce);
        //sort($arr);
        sort($arr, SORT_STRING);
        $result = sha1(join($arr));
        if ($result == $signature) {
            echo $echostr;
        }


        //接收微信公众账号接收到的信息
        $poststr = $GLOBALS["HTTP_RAW_POST_DATA"];
        $xmlObj = simplexml_load_string($poststr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $this->ToUserName = $xmlObj->ToUserName;
        $this->FromUserName = $xmlObj->FromUserName;
        $this->CreateTime = $xmlObj->CreateTime;
        $this->MsgType = $xmlObj->MsgType;
        $this->MsgEvent = $xmlObj->Event;
        $this->EventKey = $xmlObj->EventKey;


        if ($this->FromUserName) {
            //获取此用户在不同平台的唯一值
            import('weixin.lib');
            $weixin = new weixin();
            $weixin_info = $weixin->get_info($this->FromUserName);
            if (!$weixin_info) {
                return;
            }
            $this->_nickname = $weixin_info['nickname'];
            $this->_unionid = $weixin_info['unionid'];

            //检测此用户是否被绑定了
            $this->_check_weixin_bind();
            if (!$this->_third_login_id) {
                echo $this->send($this->ToUserName, $this->FromUserName, "严重系统错误");
                exit;
            }
        }

        if ($this->MsgType == 'text') {
            $Content = $xmlObj->Content;

            //默认自定义消息
            $this->_receive_text($Content);

            $keyword_info = $this->my_wxkeyword_mod->get_kword($Content, 0);
            if (!empty($keyword_info)) {
                if (is_array($keyword_info)) {
                    if (!empty($keyword_info['kecontent']) && $keyword_info['type'] == 1) {
                        echo $this->send($this->ToUserName, $this->FromUserName, $keyword_info['kecontent']);
                        exit;
                    } else {
                        $titles = unserialize($keyword_info['titles']);
                        $imageinfo = unserialize($keyword_info['imageinfo']);
                        $linkinfo = unserialize($keyword_info['linkinfo']);
                        $news = array();
                        for ($i = 0; $i < count($titles); $i++) {
                            $news[$i]['title'] = $titles[$i];
                            if (stristr($imageinfo[$i], $_SERVER['SERVER_NAME'])) {
                                $news[$i]['picurl'] = $imageinfo[$i];
                            } else {
                                $news[$i]['picurl'] = "http://" . $_SERVER['SERVER_NAME'] . '/' . $imageinfo[$i];
                            }
                            $news[$i]['url'] = $this->wx_links($linkinfo[$i]);
                        }

                        echo $this->send_pic($this->ToUserName, $this->FromUserName, $news);
                        exit;
                    }
                }
            } else {
                $id = $this->my_wxkeyword_mod->get_mess_id(0);
                $id = empty($id) ? 0 : $id;
                if ($id > 0) {
                    $wxmess = $this->my_wxkeyword_mod->get($id);
                    if (is_array($wxmess)) {
                        if (!empty($wxmess['kecontent']) && $wxmess['type'] == 1) {
                            echo $this->send($this->ToUserName, $this->FromUserName, $wxmess['kecontent']);
                            exit;
                        } else {
                            $titles = unserialize($wxmess['titles']);
                            $imageinfo = unserialize($wxmess['imageinfo']);
                            $linkinfo = unserialize($wxmess['linkinfo']);
                            $news = array();
                            for ($i = 0; $i < count($titles); $i++) {
                                $news[$i]['title'] = $titles[$i];
                                if (stristr($imageinfo[$i], $_SERVER['SERVER_NAME'])) {
                                    $news[$i]['picurl'] = $imageinfo[$i];
                                } else {
                                    $news[$i]['picurl'] = "http://" . $_SERVER['SERVER_NAME'] . '/' . $imageinfo[$i];
                                }
                                //$news[$i]['picurl'] =  str_replace('..',SITE_URL, $imageinfo[$i]);
                                $news[$i]['url'] = $this->wx_links($linkinfo[$i]);
                            }

                            echo $this->send_pic($this->ToUserName, $this->FromUserName, $news);
                            exit;
                        }
                    }//判断数组
                }//判断自动回复
            }//自动回复
        } else if ($this->MsgType == 'event') {
            if ($this->MsgEvent == 'subscribe') {
                $id = $this->my_wxkeyword_mod->get_follow_id(0);
                if ($id > 0) {
                    $wxfollow = $this->my_wxkeyword_mod->get($id);
                    if (is_array($wxfollow)) {
                        if ($wxfollow['type'] == 1) {
                            echo $this->send($this->ToUserName, $this->FromUserName, $wxfollow['kecontent']);
                            exit;
                        } else {

                            $titles = unserialize($wxfollow['titles']);
                            $imageinfo = unserialize($wxfollow['imageinfo']);
                            $linkinfo = unserialize($wxfollow['linkinfo']);
                            $news = array();
                            for ($i = 0; $i < count($titles); $i++) {
                                $news[$i]['title'] = $titles[$i];
                                if (stristr($imageinfo[$i], $_SERVER['SERVER_NAME'])) {
                                    $news[$i]['picurl'] = $imageinfo[$i];
                                } else {
                                    $news[$i]['picurl'] = "http://" . $_SERVER['SERVER_NAME'] . '/' . $imageinfo[$i];
                                }
                                $news[$i]['url'] = $this->wx_links($linkinfo[$i]);
                            }

                            echo $this->send_pic($this->ToUserName, $this->FromUserName, $news);
                            exit;
                        }
                    }//判断数组
                }//判断是否成在关注回复
            }//关注事件
            elseif ($this->MsgEvent == 'CLICK') {
                if ($this->EventKey != '') {

                    //获取用户二维码
                    if ($this->EventKey == 'member_qrcode') {
                        //用户是否被绑定了
                        if ($this->_user_id) {
                            //生成此用户的二维码
                            import('weixin.lib');
                            $weixin = new weixin();
                            $info = $weixin->get_qrcode($this->_user_id);
                            echo $this->send($this->ToUserName, $this->FromUserName, "您的分享图片地址为" . site_url() . '/' . $info['refer_qrcode_bg']);
                            exit;
                        } else {
                            echo $this->send($this->ToUserName, $this->FromUserName, "您还未绑定用户呢！");
                            exit;
                        }
                    }

                    $this->my_wxmenu_mod = & m('wxmenu');
                    $custom_key = $this->my_wxmenu_mod->getOne("select weixin_keyword from {$this->my_wxmenu_mod->table} where weixin_key='" . $this->EventKey . "'");
                    $key_list = $this->my_wxkeyword_mod->get_kword($custom_key, 0);
                    if (is_array($key_list)) {
                        if ($key_list['type'] == 1) {//文本
                            echo $this->send($this->ToUserName, $this->FromUserName, $key_list['kecontent']);
                            exit;
                        } else { //图文
                            $titles = unserialize($key_list['titles']);
                            $imageinfo = unserialize($key_list['imageinfo']);
                            $linkinfo = unserialize($key_list['linkinfo']);
                            $news = array();
                            for ($i = 0; $i < count($titles); $i++) {
                                $news[$i]['title'] = $titles[$i];
                                if (stristr($imageinfo[$i], $_SERVER['SERVER_NAME'])) {
                                    $news[$i]['picurl'] = $imageinfo[$i];
                                } else {
                                    $news[$i]['picurl'] = "http://" . $_SERVER['SERVER_NAME'] . '/' . $imageinfo[$i];
                                }
                                $news[$i]['url'] = $this->wx_links($linkinfo[$i]);
                            }
                            echo $this->send_pic($this->ToUserName, $this->FromUserName, $news);
                            exit;
                        }
                    }
                }
            }
        }
    }

    /**
     * 发送图片消息
     */
    function send_image($ToUserName, $FromUserName, $media_id) {
        $str = "<xml>
                            <ToUserName><![CDATA[%s]]></ToUserName>
                            <FromUserName><![CDATA[%s]]></FromUserName>
                            <CreateTime>%s</CreateTime>
                            <MsgType><![CDATA[%s]]></MsgType>
                            <Image>
                            <MediaId><![CDATA[%s]]></MediaId>
                            </Image>
                            </xml>";
        return $resultstr = sprintf($str, $ToUserName, $FromUserName, time(), 'image', $media_id);
    }

    /* 内部函数 */

    private function send($ToUserName, $FromUserName, $content) {
        $content .= "\n\n更多信息请输入“帮助”";
        $content = $this->wx_content($content);
        //global $ToUserName,$FromUserName;
        $str = "<xml>
				 <ToUserName><![CDATA[%s]]></ToUserName>
				 <FromUserName><![CDATA[%s]]></FromUserName>
				 <CreateTime>%s</CreateTime>
				 <MsgType><![CDATA[text]]></MsgType>
				 <Content><![CDATA[%s]]></Content>
				</xml>";
        return $resultstr = sprintf($str, $FromUserName, $ToUserName, time(), $content);
    }

    private function send_pic($ToUserName, $FromUserName, $arr) {
        //global $ToUserName,$FromUserName;
        $str = "<xml>
				 <ToUserName><![CDATA[" . $FromUserName . "]]></ToUserName>
				 <FromUserName><![CDATA[" . $ToUserName . "]]></FromUserName>
				 <CreateTime>" . time() . "</CreateTime>
				 <MsgType><![CDATA[news]]></MsgType>
				 <ArticleCount>" . count($arr) . "</ArticleCount>
				 <Articles>";
        foreach ($arr as $k => $v) {
            if ($k == 0) {
                $picurl = $v['picurl'];
            } else {
                $picurl = $v['picurl'];
            }
            $v['url'] = $this->wx_links($v['url']);
            $str .="
					 <item>
					 <Title><![CDATA[" . $v['title'] . "]]></Title> 
					 <Description><![CDATA[" . $v['description'] . "]]></Description>
					 <PicUrl><![CDATA[" . $picurl . "]]></PicUrl>
					 <Url><![CDATA[" . $v['url'] . "]]></Url>
					 </item>";
        }

        $str .= "</Articles></xml>";

        return $str;
    }

    /*
     * 链接处理  对用户新增的链接，加上  特定数值 用于自动登录  
     * 此处是处理 用户自动回复
     * user_openid    FromUserName
     * store_openid   ToUserName
     */

    private function wx_links($linkinfo) {//链接处理
        if (stristr($linkinfo, $_SERVER['SERVER_NAME'])) {
            if (stristr($linkinfo, "?")) {
                $links = $linkinfo . "&user_openid=" . $this->FromUserName . "&store_openid=" . $this->ToUserName;
            } else {
                $links = $linkinfo . "?user_openid=" . $this->FromUserName . "&store_openid=" . $this->ToUserName;
            }
        } else {
            $links = $linkinfo;
        }
        return $links;
    }

    private function wx_content($contentStr) {
        $str = $contentStr;
        $reg = '/\shref=[\'\"]([^\'"]*)[\'"]/i';
        preg_match_all($reg, $str, $out_ary); //正则：得到href的地址
        $src_ary = $out_ary[1];
        if (!empty($src_ary)) {//存在
            $comment = $src_ary[0];
            if (stristr($comment, $_SERVER['SERVER_NAME'])) {
                if (stristr($comment, "?")) {
                    $links = $comment . "&user_openid=" . $this->FromUserName . "&store_openid=" . $this->ToUserName;
                    $contentStr = str_replace($comment, $links, $str);
                } else {
                    $links = $comment . "?user_openid=" . $this->FromUserName . "&store_openid=" . $this->ToUserName;
                    $contentStr = str_replace($comment, $links, $str);
                }
            }
        }
        return $contentStr;
    }

    /**
     * 检测此微信是否绑定了用户
     */
    function _check_weixin_bind() {

        //只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段。详见：获取用户个人信息（UnionID机制）
        //判断此微信获取的 unionid 是否存在
        if ($this->_unionid) {
            $conditions = "unionid='" . $this->_unionid . "' and third_name='weixin'";
        } else {
            $conditions = "openid = '" . $this->FromUserName . "' and third_name='weixin'";
        }

        $msg = "您需要进行绑定或者注册\n\n您输入：\n绑定用户-用户名-密码\n(绑定您在本网站现有的用户)\n\n您输入：\n注册用户-用户名-密码\n(注册为您输入的用户名密码)\n\n您输入：\n自动注册\n(自动注册为本网站的会员)";
        $third_login = $this->_third_login_mod->get($conditions);

        //不存在 则添加
        if (empty($third_login)) {
            $scene_id = 0;
            if ($this->MsgType == 'event' && $this->MsgEvent == 'subscribe') {
                //事件值为0 表示不是通过扫描二维码进行的关注，没有带 事件KEY值
                if (strlen($this->EventKey) == 0) {
                    
                } else {
                    //获取扫描二维码所带的场景ID值,即为推荐人ID
                    $qrscene = $this->EventKey;
                    $scene_id_arr = explode("qrscene_", $qrscene);
                    $scene_id = intval($scene_id_arr[1]);
                }
            }

            $data = array(
                'third_name' => 'weixin',
                'openid' => $this->FromUserName,
                'user_id' => 0,
                'add_time' => gmtime(),
                'update_time' => gmtime(),
                'unionid' => $this->_unionid,
                'scene_id' => $scene_id,
            );
            $this->_third_login_id = $this->_third_login_mod->add($data);
            echo $this->send($this->ToUserName, $this->FromUserName, $msg);
            exit;
        } else {
            //赋值方便绑定
            $this->_third_login_id = $third_login['id'];
            $this->_scene_id = $third_login['scene_id'];

            if (!empty($third_login['user_id'])) {
                $member_info = $this->_member_mod->get($third_login['user_id']);
                if (empty($member_info)) {
                    $this->_third_login_mod->edit($third_login['id'], array('user_id' => 0));
                    echo $this->send($this->ToUserName, $this->FromUserName, "对不起您过去绑定的用户已不存在，" . $msg);
                    exit;
                }
                $this->_user_id = $member_info['user_id'];
                $this->_user_name = $member_info['user_name'];
            }

            //当为1时，用户的取消关注，重新通过推荐的二维码进行扫描，已经
            if ($this->_change_refer) {
                if ($this->MsgType == 'event' && $this->MsgEvent == 'subscribe') {
                    //事件值为0 表示不是通过扫描二维码进行的关注，没有带 事件KEY值
                    if (strlen($this->EventKey) == 0) {
                        
                    } else {
                        //获取扫描二维码所带的场景ID值,即为推荐人ID
                        $qrscene = $this->EventKey;
                        $scene_id_arr = explode("qrscene_", $qrscene);
                        $scene_id = intval($scene_id_arr[1]);
                        if ($scene_id) {
                            $this->_third_login_mod->edit($this->_third_login_id, array('scene_id' => $scene_id));
                            if ($this->_user_id) {
                                $this->_member_mod->edit($this->_user_id, array('referid' => $scene_id));
                            }
                        }
                    }
                }
            }
        }
    }

    /* 处理系统内置的普通文本消息 */

    function _receive_text($content) {
        if ($content == '帮助') {
            echo $this->send($this->ToUserName, $this->FromUserName, "您需要进行绑定或者注册\n\n您输入：\n绑定用户-用户名-密码\n(绑定您在本网站现有的用户)\n\n您输入：\n注册用户-用户名-密码\n(注册为您输入的用户名密码)\n\n您输入：\n自动注册\n(自动注册为本网站的会员)"
                    . "\n\n您输入：\n用户信息\n(可以查看用户当前信息)\n\n");
            exit;
        } elseif ($content == '自动注册') {
            if ($this->_user_id) {
                echo $this->send($this->ToUserName, $this->FromUserName, "对不起此微信号已经绑定了用户-" . $this->_user_name . "!\n\n您输入：\n解除绑定\n(对绑定的用户解除)");
                exit;
            } else {
                //不存在添加注册
                $ms = & ms(); //连接用户中心
                $user_id = $ms->user->register($this->_nickname, '123456', gmtime() . rand(100, 999) . '@qq.com');
                if ($user_id) {
                    $this->_do_login($user_id);
                    //自动进行绑定
                    $this->_third_login_mod->edit($this->_third_login_id, array('user_id' => $user_id));
                    //如果此微信号，是被人推荐过来的则有ID，ID为推荐人的用户ID
                    if ($this->_scene_id) {
                        $this->_member_mod->edit($user_id, array('referid' => $this->_scene_id));
                    }
                    echo $this->send($this->ToUserName, $this->FromUserName, "恭喜您，您自动注册帐号成功!\n\n您的信息为\n帐号:" . $this->_nickname . "\n密码：123456\n\n您可以通过此帐号信息在PC端网站进行登录");
                    exit;
                } else {
                    echo $this->send($this->ToUserName, $this->FromUserName, "非常抱歉，自动注册失败，用户名" . $this->_nickname . "已经被注册。\n\n您输入：\n绑定用户-用户名-密码\n(绑定您在本网站现有的用户)\n\n您输入：\n注册用户-用户名-密码\n(注册为您输入的用户名密码)");
                    exit;
                }
            }
        } elseif ($content == '解除绑定') {
            if ($this->_user_id) {
                $this->_third_login_mod->edit($this->_third_login_id, array('user_id' => '0'));
                echo $this->send($this->ToUserName, $this->FromUserName, "恭喜你解除绑定成功");
                exit;
            } else {
                echo $this->send($this->ToUserName, $this->FromUserName, "抱歉您的用户还未被绑定呢？");
                exit;
            }
        } elseif ($content == '用户信息') {
            if ($this->_user_id) {
                $member_info = $this->_member_mod->get($this->_user_id);
                $info = "帐号：" . $member_info['user_name'] . "\n" . "可用积分：" . $member_info['integral'] . "\n" . "总积分：" . $member_info['total_integral'] . "\n" .
                        "可用金额：" . $member_info['money'] . "\n" . "冻结金额：" . $member_info['money_dj'] . "\n";
                //查看此用户是否有推荐人
                if ($member_info['referid']) {
                    $refer_info = $this->_member_mod->get($member_info['referid']);
                    if ($refer_info) {
                        $info.="我的推荐人:" . $refer_info['user_name'];
                    } else {
                        $info.="我的推荐人:我有推荐人，但是用户不存在了。";
                    }
                } else {
                    $info.="我的推荐人:直接注册";
                }
                echo $this->send($this->ToUserName, $this->FromUserName, $info);
                exit;
            } else {
                echo $this->send($this->ToUserName, $this->FromUserName, "抱歉您的用户还未被绑定呢？");
                exit;
            }
        }


        $content_arr = explode("-", $content);
        if (count($content_arr) == '3') {
            if ($content_arr['0'] == '注册用户') {
                if (!$this->_user_id) {
                    if (strlen($content_arr['1']) < 6 || strlen($content_arr['2']) < 6) {
                        echo $this->send($this->ToUserName, $this->FromUserName, "输入格式有误，请重新输入!");
                        exit;
                    }
                    $ms = & ms();
                    $user_id = $ms->user->register($content_arr['1'], $content_arr['2'], gmtime() . rand(100, 999) . '@qq.com');
                    if ($user_id) {
                        $this->_do_login($user_id);
                        $this->_third_login_mod->edit($this->_third_login_id, array('user_id' => $user_id));
                        //如果此微信号，是被人推荐过来的则有ID，ID为推荐人的用户ID
                        if ($this->_scene_id) {
                            $this->_member_mod->edit($user_id, array('referid' => $this->_scene_id));
                        }
                        echo $this->send($this->ToUserName, $this->FromUserName, "恭喜您，您自动注册帐号成功!\n\n您的信息为\n帐号:" . $content_arr['1'] . "\n密码：" . $content_arr['2'] . "\n\n请牢记帐号密码\n\n您可以通过此帐号信息在PC端网站进行登录");
                        exit;
                    } else {
                        echo $this->send($this->ToUserName, $this->FromUserName, "对不起注册失败，请重新更换用户名！");
                        exit;
                    }
                } else {
                    echo $this->send($this->ToUserName, $this->FromUserName, "您已经绑定了帐户-" . $this->_user_name . "\n\n您输入：\n解除绑定\n(对绑定的用户解除)");
                    exit;
                }
            }
            if ($content_arr['0'] == '绑定用户') {
                if ($this->_user_id) {
                    echo $this->send($this->ToUserName, $this->FromUserName, "您已经绑定了帐户-" . $this->_user_name . "\n\n您输入：\n解除绑定\n(对绑定的用户解除)");
                    exit;
                } else {
                    if (strlen($content_arr['1']) < 6 || strlen($content_arr['2']) < 6) {
                        echo $this->send($this->ToUserName, $this->FromUserName, "输入格式有误，请重新输入!");
                        exit;
                    }


                    $ms = & ms();
                    $user_id = $ms->user->auth($content_arr['1'], $content_arr['2']);
                    if ($user_id) {

                        //查看此用户是否被绑定了。
                        $third_login = $this->_third_login_mod->get("user_id=" . $user_id . " and third_name='weixin'");
                        if ($third_login) {
                            echo $this->send($this->ToUserName, $this->FromUserName, "对不起绑定失败，此用户已经被绑定了。");
                            exit;
                        } else {
                            $this->_third_login_mod->edit($this->_third_login_id, array('user_id' => $user_id));
                            echo $this->send($this->ToUserName, $this->FromUserName, "恭喜您，您绑定帐号成功!\n\n您的信息为\n帐号:" . $content_arr['1'] . "\n密码：" . $content_arr['2'] . "\n\n请牢记帐号密码\n\n您可以通过此帐号信息在PC端网站进行登录");
                            exit;
                        }
                    } else {
                        echo $this->send($this->ToUserName, $this->FromUserName, "对不起绑定失败，请确定用户名密码");
                        exit;
                    }
                }
            }
        }
    }

}

?>